namespace ScrumSprintMonitor.ConfigEditor.Views.ConfigurationView
{
    #region #using Directives

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    using System.Windows;
    using System.Windows.Input;

    using Implementation;
    using Implementation.Configuration;

    using Infrastructure;
    using Infrastructure.Configuration;

    using Microsoft.Practices.Composite.Presentation.Commands;
    using Microsoft.Practices.ServiceLocation;
    using Microsoft.Practices.Unity;
    using Microsoft.Win32;

    using PresentationConfigurationEditorView;

    using Properties;

    using SprintConfigurationEditorView;

    using UI.Wpf;
    using UI.Wpf.ViewModels;

    #endregion

    public class ConfigurationViewModel : ViewModelBase,
                                          IConfigurationViewModel
    {
        private readonly Dictionary<string, Uri> availableTfsServers = new Dictionary<string, Uri>();
        private readonly DelegateCommand<Window> browsePresentationConfigurationCommand;
        private readonly DelegateCommand<Window> browseSprintConfigurationCommand;
        private readonly DelegateCommand<Window> browseTeamMembersConfigurationCommand;
        private readonly DelegateCommand<Window> cancelCommand;
        private readonly DelegateCommand<Window> editPresentationConfigurationCommand;
        private readonly DelegateCommand<Window> editSprintConfigurationCommand;
        private readonly DelegateCommand<Window> editTeamMembersConfigurationCommand;
        private readonly DelegateCommand<Window> generateTeamMembersConfigurationCommand;
        private readonly DelegateCommand<Window> helpCommand;
        private readonly DelegateCommand<Window> okCommand;
        private readonly DelegateCommand<Window> viewLogFileCommand;
        private bool isBusy;

        static ConfigurationViewModel()
        {
            var dependsOn = Register<ConfigurationViewModel>();

            dependsOn.Call(me => me.OnPropertyChanged("IsConsiderOutlookTentativeAsFreeTimeEnabled")).OnChanged(me => me.EnableOutlookIntegration).
                OnChanged(me => me.IsConfigurationWritable);
            dependsOn.Call(me => me.OnPropertyChanged("IsShowBurndownChartEnabled")).OnChanged(me => me.InPlanningMode).OnChanged(
                me => me.IsConfigurationWritable);
            dependsOn.Call(me => me.OnTfsServerNameChanged()).OnChanged(me => me.TfsServerName);

            dependsOn.Call(me => me.editSprintConfigurationCommand.RaiseCanExecuteChanged()).OnChanged(me => me.ConfigurationFilePath);
            dependsOn.Call(me => me.generateTeamMembersConfigurationCommand.RaiseCanExecuteChanged()).OnChanged(me => me.ConfigurationFilePath);
            dependsOn.Call(me => me.editTeamMembersConfigurationCommand.RaiseCanExecuteChanged()).OnChanged(me => me.TeamMembersConfigurationFilePath);
            dependsOn.Call(me => me.editPresentationConfigurationCommand.RaiseCanExecuteChanged()).OnChanged(
                me => me.PresentationConfigurationFilePath);
            dependsOn.Call(me => me.okCommand.RaiseCanExecuteChanged()).OnChanged(me => me.ConfigurationFilePath).OnChanged(
                me => me.TeamMembersConfigurationFilePath).OnChanged(me => me.PresentationConfigurationFilePath).OnChanged(me => me.TfsServerName);
        }

        public ConfigurationViewModel()
        {
            this.browsePresentationConfigurationCommand = new DelegateCommand<Window>(BrowsePresentationConfiguration,
                                                                                      CanBrowsePresentationConfiguration);
            this.browseSprintConfigurationCommand = new DelegateCommand<Window>(BrowseSprintConfiguration, CanBrowseSprintConfiguration);
            this.browseTeamMembersConfigurationCommand = new DelegateCommand<Window>(BrowseTeamMembersConfiguration, CanBrowseTeamMembersConfiguration);
            this.editPresentationConfigurationCommand = new DelegateCommand<Window>(EditPresentationConfiguration, CanEditPresentationConfiguration);
            this.editSprintConfigurationCommand = new DelegateCommand<Window>(EditSprintConfiguration, CanEditSprintConfiguration);
            this.generateTeamMembersConfigurationCommand = new DelegateCommand<Window>(GenerateTeamMembersConfiguration,
                                                                                       CanGenerateTeamMembersConfiguration);
            this.editTeamMembersConfigurationCommand = new DelegateCommand<Window>(EditTeamMembersConfiguration, CanEditTeamMembersConfiguration);
            this.viewLogFileCommand = new DelegateCommand<Window>(ViewLogFile, CanViewLogFile);
            this.okCommand = new DelegateCommand<Window>(OnOk, CanCloseWithOk);
            this.cancelCommand = new DelegateCommand<Window>(OnCancel, CanCloseWithCancel);
            this.helpCommand = new DelegateCommand<Window>(OnHelp);

            PopulateTfsServerNamesList();
        }

        protected string HomePath
        {
            get { return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); }
        }

        #region IConfigurationViewModel Members

        public bool IsConfigurationWritable
        {
            [DebuggerStepThrough]
            get { return !Settings.Default.IsReadOnly; }
        }

        public bool IsBusy
        {
            [DebuggerStepThrough]
            get { return this.isBusy; }
            set
            {
                if (value != this.isBusy)
                {
                    this.isBusy = value;

                    OnPropertyChanged("IsBusy");
                }
            }
        }

        public IDictionary<string, Uri> AvailableTfsServers
        {
            [DebuggerStepThrough]
            get { return this.availableTfsServers; }
        }

        public string TfsServerName
        {
            [DebuggerStepThrough]
            get { return Settings.Default.TfsServerName; }
            set
            {
                if (value != Settings.Default.TfsServerName)
                {
                    Settings.Default.TfsServerName = value;

                    OnPropertyChanged("TfsServerName");
                }
            }
        }

        public Uri TfsServerUri
        {
            [DebuggerStepThrough]
            get { return string.IsNullOrWhiteSpace(Settings.Default.TfsServerUri) ? null : new Uri(Settings.Default.TfsServerUri); }
            private set
            {
                if (value != TfsServerUri)
                {
                    Settings.Default.TfsServerUri = (value != null ? value.AbsoluteUri : null);

                    OnPropertyChanged("TfsServerUri");
                }
            }
        }

        public string TfsServerUserName
        {
            [DebuggerStepThrough]
            get { return Settings.Default.TfsServerUserName; }
            set
            {
                if (value != Settings.Default.TfsServerUserName)
                {
                    Settings.Default.TfsServerUserName = value;

                    OnPropertyChanged("TfsServerUserName");
                }
            }
        }

        public string TfsServerPassword
        {
            [DebuggerStepThrough]
            get { return Settings.Default.TfsServerPassword; }
            set
            {
                if (value != Settings.Default.TfsServerPassword)
                {
                    Settings.Default.TfsServerPassword = value;

                    OnPropertyChanged("TfsServerPassword");
                }
            }
        }

        public string ConfigurationFilePath
        {
            get { return ShortenPath(HomePath, Settings.Default.ConfigurationFilePath); }
            set
            {
                string newValue = GetFullPath(value);

                if (newValue != Settings.Default.ConfigurationFilePath)
                {
                    Settings.Default.ConfigurationFilePath = newValue;

                    OnPropertyChanged("ConfigurationFilePath");
                }
            }
        }

        public ICommand BrowseSprintConfigurationCommand
        {
            [DebuggerStepThrough]
            get { return this.browseSprintConfigurationCommand; }
        }

        public ICommand EditSprintConfigurationCommand
        {
            [DebuggerStepThrough]
            get { return this.editSprintConfigurationCommand; }
        }

        public string TeamMembersConfigurationFilePath
        {
            [DebuggerStepThrough]
            get { return ShortenPath(HomePath, Settings.Default.TeamMembersConfigurationFilePath); }
            set
            {
                string newValue = GetFullPath(value);

                if (newValue != Settings.Default.TeamMembersConfigurationFilePath)
                {
                    Settings.Default.TeamMembersConfigurationFilePath = newValue;

                    OnPropertyChanged("TeamMembersConfigurationFilePath");
                }
            }
        }

        public ICommand BrowseTeamMembersConfigurationCommand
        {
            [DebuggerStepThrough]
            get { return this.browseTeamMembersConfigurationCommand; }
        }

        public ICommand GenerateTeamMembersConfigurationCommand
        {
            [DebuggerStepThrough]
            get { return this.generateTeamMembersConfigurationCommand; }
        }

        public ICommand EditTeamMembersConfigurationCommand
        {
            [DebuggerStepThrough]
            get { return this.editTeamMembersConfigurationCommand; }
        }

        public string PresentationConfigurationFilePath
        {
            get { return ShortenPath(HomePath, Settings.Default.PresentationConfigurationFilePath); }
            set
            {
                string newValue = GetFullPath(value);

                if (newValue != Settings.Default.PresentationConfigurationFilePath)
                {
                    Settings.Default.PresentationConfigurationFilePath = newValue;

                    OnPropertyChanged("PresentationConfigurationFilePath");
                }
            }
        }

        public ICommand BrowsePresentationConfigurationCommand
        {
            [DebuggerStepThrough]
            get { return this.browsePresentationConfigurationCommand; }
        }

        public ICommand EditPresentationConfigurationCommand
        {
            [DebuggerStepThrough]
            get { return this.editPresentationConfigurationCommand; }
        }

        //public bool CanEditMachineWakeUpSetting
        //{
        //    [DebuggerStepThrough]
        //    get { return IsConfigurationWritable; }
        //}

        //public bool WakeUpMachine
        //{
        //    [DebuggerStepThrough]
        //    get { return Settings.Default.WakeUpMachine; }
        //    set
        //    {
        //        if (value != Settings.Default.WakeUpMachine)
        //        {
        //            Settings.Default.WakeUpMachine = value;

        //            OnPropertyChanged("WakeUpMachine");
        //        }
        //    }
        //}

        //public TimeSpan TimeOfDayToWakeUpMachine
        //{
        //    [DebuggerStepThrough]
        //    get { return Settings.Default.TimeOfDayToWakeUpMachine; }
        //    set
        //    {
        //        if (value != Settings.Default.TimeOfDayToWakeUpMachine)
        //        {
        //            Settings.Default.TimeOfDayToWakeUpMachine = value;

        //            OnPropertyChanged("TimeOfDayToWakeUpMachine");
        //        }
        //    }
        //}

        public bool CanEditSuspendMachineSetting
        {
            [DebuggerStepThrough]
            get { return IsConfigurationWritable && NativeMethods.IsPwrSuspendAllowed(); }
        }

        public bool SuspendMachine
        {
            [DebuggerStepThrough]
            get { return Settings.Default.SuspendMachine; }
            set
            {
                if (value != Settings.Default.SuspendMachine)
                {
                    Settings.Default.SuspendMachine = value;

                    OnPropertyChanged("SuspendMachine");
                }
            }
        }

        public TimeSpan TimeOfDayToSuspendMachine
        {
            [DebuggerStepThrough]
            get { return Settings.Default.TimeOfDayToSuspendMachine; }
            set
            {
                if (value != Settings.Default.TimeOfDayToSuspendMachine)
                {
                    Settings.Default.TimeOfDayToSuspendMachine = value;

                    OnPropertyChanged("TimeOfDayToSuspendMachine");
                }
            }
        }

        public bool EnableOutlookIntegration
        {
            [DebuggerStepThrough]
            get { return Settings.Default.EnableOutlookIntegration; }
            set
            {
                if (value != Settings.Default.EnableOutlookIntegration)
                {
                    Settings.Default.EnableOutlookIntegration = value;

                    OnPropertyChanged("EnableOutlookIntegration");
                }
            }
        }

        public bool ConsiderOutlookTentativeAsFreeTime
        {
            [DebuggerStepThrough]
            get { return Settings.Default.ConsiderOutlookTentativeAsFreeTime; }
            set
            {
                if (value != Settings.Default.ConsiderOutlookTentativeAsFreeTime)
                {
                    Settings.Default.ConsiderOutlookTentativeAsFreeTime = value;

                    OnPropertyChanged("ConsiderOutlookTentativeAsFreeTime");
                }
            }
        }

        public bool IsConsiderOutlookTentativeAsFreeTimeEnabled
        {
            [DebuggerStepThrough]
            get { return IsConfigurationWritable && EnableOutlookIntegration; }
        }

        public bool ReportUnestimatedSprintBacklogItems
        {
            [DebuggerStepThrough]
            get { return Settings.Default.ReportUnestimatedSprintBacklogItems; }
            set
            {
                if (value != Settings.Default.ReportUnestimatedSprintBacklogItems)
                {
                    Settings.Default.ReportUnestimatedSprintBacklogItems = value;

                    OnPropertyChanged("ReportUnestimatedSprintBacklogItems");
                }
            }
        }

        public bool OptInCEIP
        {
            [DebuggerStepThrough]
            get { return Settings.Default.OptInCEIP; }
            set
            {
                if (value != Settings.Default.OptInCEIP)
                {
                    Settings.Default.OptInCEIP = value;

                    OnPropertyChanged("OptInCEIP");
                }
            }
        }

        public bool InPlanningMode
        {
            [DebuggerStepThrough]
            get { return Settings.Default.ActiveSprintMode == SprintMode.Planning; }
            set
            {
                if (value != InPlanningMode)
                {
                    Settings.Default.ActiveSprintMode = (value ? SprintMode.Planning : SprintMode.Sprinting);

                    OnPropertyChanged("InPlanningMode");
                }
            }
        }

        public bool UseMultipleMonitors
        {
            [DebuggerStepThrough]
            get { return Settings.Default.UseMultipleMonitors; }
            set
            {
                if (value != UseMultipleMonitors)
                {
                    Settings.Default.UseMultipleMonitors = value;

                    OnPropertyChanged("UseMultipleMonitors");
                }
            }
        }

        public bool IsShowBurndownChartEnabled
        {
            [DebuggerStepThrough]
            get { return IsConfigurationWritable && !InPlanningMode; }
        }

        public bool ShowBurndownChart
        {
            [DebuggerStepThrough]
            get { return Settings.Default.ShowBurndownChart; }
            set
            {
                if (value != ShowBurndownChart)
                {
                    Settings.Default.ShowBurndownChart = value;

                    OnPropertyChanged("ShowBurndownChart");
                }
            }
        }

        public ICommand ViewLogFileCommand
        {
            [DebuggerStepThrough]
            get { return this.viewLogFileCommand; }
        }

        public ICommand OkCommand
        {
            [DebuggerStepThrough]
            get { return this.okCommand; }
        }

        public ICommand CancelCommand
        {
            [DebuggerStepThrough]
            get { return this.cancelCommand; }
        }

        public ICommand HelpCommand
        {
            [DebuggerStepThrough]
            get { return this.helpCommand; }
        }

        public void OnViewActivated()
        {
            this.editSprintConfigurationCommand.RaiseCanExecuteChanged();
            this.generateTeamMembersConfigurationCommand.RaiseCanExecuteChanged();
            this.editTeamMembersConfigurationCommand.RaiseCanExecuteChanged();
            this.editPresentationConfigurationCommand.RaiseCanExecuteChanged();
            this.okCommand.RaiseCanExecuteChanged();
        }

        #endregion

        #region Commands

        private static bool CanCloseWithCancel(Window configurationWindow)
        {
            return true;
        }

        private static void OnCancel(Window configurationWindow)
        {
            configurationWindow.DialogResult = false;
            configurationWindow.Close();
        }

        private static void OnHelp(Window configurationWindow)
        {
            try
            {
                Process.Start(@"http://sweux.com/blogs/pombeiro/index.php/scrum-sprint-monitor-clickonce-installation/configuration");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private bool CanCloseWithOk(Window configurationWindow)
        {
            return IsConfigurationFilePathValid(ConfigurationFilePath) && IsConfigurationFilePathValid(TeamMembersConfigurationFilePath) &&
                   IsConfigurationFilePathValid(PresentationConfigurationFilePath) && TfsServerUri != null &&
                   !string.IsNullOrEmpty(TfsServerUri.AbsoluteUri);
        }

        private static void OnOk(Window configurationWindow)
        {
            configurationWindow.DialogResult = true;
            configurationWindow.Close();
        }

        private static bool CanBrowseTeamMembersConfiguration(Window configurationWindow)
        {
            return true;
        }

        private void BrowseTeamMembersConfiguration(Window configurationWindow)
        {
            var usageIdentifierGuid = new Guid("{9697D713-08B8-446f-96E3-C59300AF2BC1}");

            // Configure open file dialog box
            string filePath = GetFullPath(TeamMembersConfigurationFilePath);
            string newFilePath = UI.Wpf.FileDialog.ShowFileOpenDialog(configurationWindow, filePath,
                                                                      Resources.OpenFileDialog_TeamMembersConfigurationFile_Title,
                                                                      Resources.OpenFileDialog_TeamMembersConfigurationFile_Filter, ".xml",
                                                                      "team-info.xml", usageIdentifierGuid);

            // Process open file dialog box results
            if (newFilePath != null)
            {
                // Open document
                TeamMembersConfigurationFilePath = newFilePath;
            }
        }

        private static bool CanBrowsePresentationConfiguration(Window configurationWindow)
        {
            return true;
        }

        private void BrowsePresentationConfiguration(Window configurationWindow)
        {
            var usageIdentifierGuid = new Guid("{0AA5C971-8539-480e-B009-7F8ECA8C9A75}");

            // Configure open file dialog box
            string filePath = GetFullPath(PresentationConfigurationFilePath);
            string newFilePath = UI.Wpf.FileDialog.ShowFileOpenDialog(configurationWindow, filePath,
                                                                      Resources.OpenFileDialog_PresentationConfigurationFile_Title,
                                                                      Resources.OpenFileDialog_PresentationConfigurationFile_Filter, ".txt",
                                                                      "PresentationConfiguration.txt", usageIdentifierGuid);

            // Process open file dialog box results
            if (newFilePath != null)
            {
                // Open document
                PresentationConfigurationFilePath = newFilePath;
            }
        }

        private static bool CanBrowseSprintConfiguration(Window configurationWindow)
        {
            return true;
        }

        private void BrowseSprintConfiguration(Window configurationWindow)
        {
            var usageIdentifierGuid = new Guid("{40AA5246-11CD-4dd7-9B55-54B49CF98503}");

            // Configure open file dialog box
            string filePath = GetFullPath(ConfigurationFilePath);
            string newFilePath = UI.Wpf.FileDialog.ShowFileOpenDialog(configurationWindow, filePath, Resources.OpenFileDialog_ConfigurationFile_Title,
                                                                      Resources.OpenFileDialog_ConfigurationFile_Filter, ".txt",
                                                                      "SprintConfiguration.txt", usageIdentifierGuid);

            // Process open file dialog box results
            if (newFilePath != null)
            {
                // Open document
                ConfigurationFilePath = newFilePath;

                CheckIfNeedToMoveToNewFolder(configurationWindow, newFilePath);
            }
        }

        private bool IsConfigurationFilePathValid(string filePath)
        {
            return File.Exists(GetFullPath(filePath));
        }

        private bool CanEditTeamMembersConfiguration(Window configurationWindow)
        {
            return IsConfigurationFilePathValid(TeamMembersConfigurationFilePath);
        }

        private void EditTeamMembersConfiguration(Window configurationWindow)
        {
            const string excelFileName = "excel.exe";

            try
            {
                configurationWindow.Cursor = Cursors.Wait;
                try
                {
                    var excelProcess = Process.Start(excelFileName, string.Format("\"{0}\"", GetFullPath(TeamMembersConfigurationFilePath)));
                    if (excelProcess != null)
                    {
                        excelProcess.WaitForInputIdle(10000);
                    }
                }
                finally
                {
                    configurationWindow.Cursor = null;
                }
            }
            catch (Win32Exception ex)
            {
                if (ex.NativeErrorCode == 2)
                {
                    MessageBox.Show(string.Format("Could not find '{0}'. Do you have Microsoft Excel 2007 installed?", excelFileName),
                                    Application.Current.MainWindow.Title);
                }
                else
                {
                    MessageBox.Show(ex.Message, Application.Current.MainWindow.Title);
                }
            }
        }

        private bool CanGenerateTeamMembersConfiguration(Window configurationWindow)
        {
            return IsConfigurationFilePathValid(ConfigurationFilePath);
        }

        private void GenerateTeamMembersConfiguration(Window configurationWindow)
        {
            configurationWindow.Cursor = Cursors.Wait;

            TeamConfigurationGenerator teamConfigGenerator = null;
            bool successful = false;

            try
            {
                var container = ServiceLocator.Current.GetInstance<IUnityContainer>();

                teamConfigGenerator = new TeamConfigurationGenerator(container);
                teamConfigGenerator.Started += OnStartedGeneratingTeamConfig;
                teamConfigGenerator.Finished += OnFinishedGeneratingTeamConfig;

                successful = teamConfigGenerator.GenerateConfiguration(this);
            }
            catch (Exception ex)
            {
                ServiceLocator.Current.GetInstance<ILogger<ConfigurationViewModel>>().Error(ex,
                                                                                            "Exception found while generating team member configuration.");

                MessageBox.Show(ex.Message, Application.Current.MainWindow.Title);
            }
            finally
            {
                if (!successful && teamConfigGenerator != null)
                {
                    teamConfigGenerator.Finished -= OnFinishedGeneratingTeamConfig;
                    teamConfigGenerator.Dispose();
                }

                configurationWindow.Cursor = null;
            }
        }

        private void OnStartedGeneratingTeamConfig(object sender, EventArgs e)
        {
            IsBusy = true;
        }

        private void OnFinishedGeneratingTeamConfig(object sender, EventArgs e)
        {
            var teamConfigGenerator = (TeamConfigurationGenerator) sender;

            teamConfigGenerator.Dispose();

            // Signal that the team members file has changed
            OnPropertyChanged("TeamMembersConfigurationFilePath");

            IsBusy = false;
        }

        private bool CanEditPresentationConfiguration(Window configurationWindow)
        {
            return IsConfigurationFilePathValid(PresentationConfigurationFilePath);
        }

        private static void EditPresentationConfiguration(Window configurationWindow)
        {
            configurationWindow.Cursor = Cursors.Wait;
            try
            {
                var container = ServiceLocator.Current.GetInstance<IUnityContainer>();
                var configuration =
                    container.Resolve<StreamBasedPresentationConfiguration>(new ParameterOverride("streamProvider",
                                                                                                  container.Resolve<FileDataStreamProvider>(
                                                                                                      new ParameterOverride("filePath",
                                                                                                                            Settings.Default.
                                                                                                                                PresentationConfigurationFilePath))));
                var model = container.Resolve<IPresentationConfigurationEditorViewModel>(new ParameterOverride("configuration", configuration));
                var window = new PresentationConfigurationEditorWindow(model)
                                 {
                                     Owner = configurationWindow
                                 };
                window.ShowDialog();
            }
            catch (Exception ex)
            {
                ServiceLocator.Current.GetInstance<ILogger<ConfigurationViewModel>>().Error(ex,
                                                                                            "Exception found while opening presentation configuration editor.");

                MessageBox.Show(ex.Message, Application.Current.MainWindow.Title);
            }
            finally
            {
                configurationWindow.Cursor = null;
            }
        }

        private bool CanEditSprintConfiguration(Window configurationWindow)
        {
            return IsConfigurationFilePathValid(ConfigurationFilePath);
        }

        private static void EditSprintConfiguration(Window configurationWindow)
        {
            configurationWindow.Cursor = Cursors.Wait;
            try
            {
                var container = ServiceLocator.Current.GetInstance<IUnityContainer>();
                var configuration =
                    container.Resolve<StreamBasedSprintConfiguration>(new ParameterOverride("streamProvider",
                                                                                            container.Resolve<FileDataStreamProvider>(
                                                                                                new ParameterOverride("filePath",
                                                                                                                      Settings.Default.
                                                                                                                          ConfigurationFilePath))));
                var model = container.Resolve<ISprintConfigurationEditorViewModel>(new ParameterOverride("configuration", configuration));
                var window = new SprintConfigurationEditorWindow(model)
                                 {
                                     Owner = configurationWindow
                                 };
                window.ShowDialog();
            }
            catch (Exception ex)
            {
                ServiceLocator.Current.GetInstance<ILogger<ConfigurationViewModel>>().Error(ex,
                                                                                            "Exception found while opening sprint configuration editor.");

                MessageBox.Show(ex.Message, Application.Current.MainWindow.Title);
            }
            finally
            {
                configurationWindow.Cursor = null;
            }
        }

        private static bool CanViewLogFile(Window configurationWindow)
        {
            return true;
        }

        private static void ViewLogFile(Window configurationWindow)
        {
            try
            {
                configurationWindow.Cursor = Cursors.Wait;
                try
                {
                    const string logFileBaseName = "scrumsprintmonitor.log";
                    string assemblyLocation = Assembly.GetEntryAssembly().Location;
                    var versionInfo = FileVersionInfo.GetVersionInfo(assemblyLocation);
                    string appDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
                                                        versionInfo.CompanyName.Replace(' ', '_'));
                    string logFileName = Path.Combine(appDataFolder, logFileBaseName);

                    var process = Process.Start(logFileName);
                    if (process != null)
                    {
                        process.WaitForInputIdle(10000);
                    }
                }
                finally
                {
                    configurationWindow.Cursor = null;
                }
            }
            catch (Win32Exception ex)
            {
                MessageBox.Show(ex.Message, Application.Current.MainWindow.Title);
            }
        }

        #endregion

        #region Private Methods

        private string GetFullPath(string path)
        {
            return Path.GetFullPath(Path.Combine(HomePath, path));
        }

        private void PopulateTfsServerNamesList()
        {
            for (int version = 8; version <= 15; ++version)
            {
                string keyPath = string.Format(@"Software\Microsoft\VisualStudio\{0}.0\TeamFoundation\{1}", version,
                                               (version >= 10 ? "Instances" : "Servers"));

                using (var key = Registry.CurrentUser.OpenSubKey(keyPath, false))
                {
                    if (key != null)
                    {
                        if (version >= 10)
                        {
                            var availableTfsServerNames = key.GetSubKeyNames();

                            foreach (string availableTfsServerName in availableTfsServerNames.OrderBy(x => x))
                            {
                                using (var tfsServerKey = key.OpenSubKey(availableTfsServerName, false))
                                {
                                    if (tfsServerKey != null)
                                    {
                                        var tfsProjectCollectionsKey = tfsServerKey.OpenSubKey("Collections");
                                        if (tfsProjectCollectionsKey == null)
                                        {
                                            continue;
                                        }

                                        var availableTfsProjectCollections = tfsProjectCollectionsKey.GetSubKeyNames();

                                        foreach (string availableCollection in availableTfsProjectCollections.OrderBy(x => x))
                                        {
                                            using (var tfsProjectCollectionKey = tfsProjectCollectionsKey.OpenSubKey(availableCollection, false))
                                            {
                                                if (tfsProjectCollectionKey != null)
                                                {
                                                    var projectCollectionUri =
                                                        new Uri((string) tfsProjectCollectionKey.GetValue("Uri", availableCollection),
                                                                UriKind.Absolute);
                                                    this.availableTfsServers.Add(
                                                        string.Format("{0} - {1}", availableTfsServerName, availableCollection), projectCollectionUri);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            var availableTfsServerNames = key.GetValueNames();

                            foreach (string availableTfsServerName in availableTfsServerNames.OrderBy(x => x))
                            {
                                var uri = new Uri((string) key.GetValue(availableTfsServerName, availableTfsServerName), UriKind.Absolute);

                                this.availableTfsServers.Add(availableTfsServerName, uri);
                            }
                        }
                    }
                }
            }

            if (!string.IsNullOrEmpty(TfsServerName) &&
                !this.availableTfsServers.Keys.Any(x => string.Equals(x, TfsServerName, StringComparison.OrdinalIgnoreCase)))
            {
                this.availableTfsServers.Add(TfsServerName, TfsServerUri);
            }

            OnTfsServerNameChanged();
        }

        private void OnTfsServerNameChanged()
        {
            Uri tfsServerUri;
            if (AvailableTfsServers.TryGetValue(TfsServerName, out tfsServerUri))
            {
                TfsServerUri = tfsServerUri;
            }
        }

        private static string ShortenPath(string mainDirPath, string absoluteFilePath)
        {
            string newPath = EvaluateRelativePath(mainDirPath, Path.GetFullPath(absoluteFilePath));

            if (newPath.Length > absoluteFilePath.Length)
            {
                return absoluteFilePath;
            }

            return newPath;
        }

        private static string EvaluateRelativePath(string mainDirPath, string absoluteFilePath)
        {
            if (Path.GetPathRoot(mainDirPath) != Path.GetPathRoot(absoluteFilePath))
            {
                return absoluteFilePath;
            }

            var firstPathParts = mainDirPath.Trim(Path.DirectorySeparatorChar).Split(Path.DirectorySeparatorChar);
            var secondPathParts = absoluteFilePath.Trim(Path.DirectorySeparatorChar).Split(Path.DirectorySeparatorChar);

            int sameCounter = 0;
            for (int i = 0; i < Math.Min(firstPathParts.Length, secondPathParts.Length); i++)
            {
                if (string.Compare(firstPathParts[i], secondPathParts[i].ToLower(), StringComparison.OrdinalIgnoreCase) != 0)
                {
                    break;
                }
                sameCounter++;
            }

            if (sameCounter == 0)
            {
                return absoluteFilePath;
            }

            string newPath = string.Empty;
            for (int i = sameCounter; i < firstPathParts.Length; i++)
            {
                if (i > sameCounter)
                {
                    newPath += Path.DirectorySeparatorChar;
                }
                newPath += "..";
            }
            if (newPath.Length == 0)
            {
                newPath = ".";
            }
            for (int i = sameCounter; i < secondPathParts.Length; i++)
            {
                newPath += Path.DirectorySeparatorChar;
                newPath += secondPathParts[i];
            }

            return newPath;
        }

        private void CheckIfNeedToMoveToNewFolder(Window configurationWindow, string path)
        {
            string newFolder = Path.GetDirectoryName(path);
            string newSprintConfigurationFilePath = Path.Combine(newFolder, Path.GetFileName(ConfigurationFilePath));
            string newPresentationConfigurationFilePath = Path.Combine(newFolder, Path.GetFileName(PresentationConfigurationFilePath));
            string newTeamMembersConfigurationFilePath = Path.Combine(newFolder, Path.GetFileName(TeamMembersConfigurationFilePath));

            if (Path.GetDirectoryName(PresentationConfigurationFilePath) != newFolder &&
                Path.GetDirectoryName(TeamMembersConfigurationFilePath) != newFolder)
            {
                if (File.Exists(newSprintConfigurationFilePath) && File.Exists(newPresentationConfigurationFilePath) &&
                    File.Exists(newTeamMembersConfigurationFilePath))
                {
                    var result = MessageBox.Show(configurationWindow, Resources.Prompt_Question_UseTargetFolderConfigurationFileSet,
                                                 Resources.ProductName, MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.Yes);

                    if (result == MessageBoxResult.Yes)
                    {
                        ConfigurationFilePath = newSprintConfigurationFilePath;
                        TeamMembersConfigurationFilePath = newTeamMembersConfigurationFilePath;
                        PresentationConfigurationFilePath = newPresentationConfigurationFilePath;
                    }
                }
            }
        }

        #endregion
    }
}
